﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Db4objects.Db4o;
using Db4objects.Db4o.CS;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.Config;
using Db4objects.Db4o.Constraints;
using DataLayer.Model;
using System.IO;

namespace DataLayer.Core
{
    public class Server
    {
        private static bool _isStarted = false;
        private static IObjectServer _server = null;
        private static IConfiguration _config = null;
        private static int _nConn = 0;

        private static string _databaseLocation = null;
        private static string _directoryDatabaseLocation = null;

        static Server()
        {
            StartServer();
        }

        private static void StartServer()
        {
            if (!_isStarted)
            {
                _config = Db4oFactory.Configure();
                _config.ObjectClass(typeof(Lancamento)).ObjectField("<ID>k__BackingField").Indexed(true);
                _config.Add(new UniqueFieldValueConstraint(typeof(Lancamento), "<ID>k__BackingField"));
                _config.ObjectClass(typeof(Categoria)).ObjectField("<ID>k__BackingField").Indexed(true);
                _config.Add(new UniqueFieldValueConstraint(typeof(Categoria), "<ID>k__BackingField"));
                _config.ObjectClass(typeof(Lancamento)).ObjectField("<ID>k__BackingField").Indexed(true);
                _config.Add(new UniqueFieldValueConstraint(typeof(Lancamento), "<ID>k__BackingField"));

                _isStarted = true;
                _directoryDatabaseLocation = AppDomain.CurrentDomain.BaseDirectory + "db\\";
                _databaseLocation = AppDomain.CurrentDomain.BaseDirectory + "db\\database.db";
                _server = Db4oFactory.OpenServer(_config, _databaseLocation, 0);

                UpdateDatabase();
            }
        }

        private static void UpdateDatabase()
        {
            IObjectContainer client = OpenClient();
            IEnumerable<Model.System> isys = (from Model.System s in client
                                              select s);
            if (isys.Count() == 0)
            {
                Model.System sys = new DataLayer.Model.System();
                sys.ID = Guid.NewGuid();
                sys.Version = 0;
                client.Store(sys);
                client.Commit();

                isys = (from Model.System s in client
                        select s);
            }

            Model.System system = isys.Single();

            if (system.Version == 0)
            {
                /*ATUALIZAÇÃO PARA INCLUSÃO DE TRANSFERENCIA ENTRE CONTAS*/
                Model.Categoria catIn = new Categoria();
                catIn.Descricao = "TRANSFERENCIA";
                catIn.TipoLancamento = Categoria.eTipoLancamento.Entrada;
                catIn.Salvar();

                Model.Categoria catOut = new Categoria();
                catOut.Descricao = "TRANSFERENCIA";
                catOut.TipoLancamento = Categoria.eTipoLancamento.Saida;
                catOut.Salvar();

                system.IDTransferenciaOut = catIn.ID;
                system.IDTransferenciaIN = catOut.ID;
                system.Version++;
                client.Store(system);
                client.Commit();
            }

        }

        public static IObjectContainer OpenClient()
        {
            _nConn++;
            //StartServer();
            return _server.OpenClient();
        }

        public static void CloseClient(IObjectContainer client)
        {
            client.Close();

            /*if (--_nConn == 0)
            {
                _server.Close();
                _server = null;
                _isStarted = false;
                _config = null;
            }*/
        }

        public static void CreateBackup()
        {
            //OpenClient().Ext().Backup(_directoryDatabaseLocation + "bk\\" + DateTime.Now.ToFileTimeUtc() + ".db");
            if (_server != null)
            {
                _server.Close();
                _server = null;
            }
            _isStarted = false;
            _config = null;


            byte[] DataBytes = System.IO.File.ReadAllBytes(_databaseLocation);
            byte[] Compressed = SevenZip.Compression.LZMA.SevenZipHelper.Compress(DataBytes);
            File.WriteAllBytes(_directoryDatabaseLocation + "bk\\" + DateTime.Now.ToFileTimeUtc() + ".7zip", Compressed);


            /*
             ICSharpCode.SharpZipLib.Zip.FastZip zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
             zip.CreateZip(_directoryDatabaseLocation + "bk\\" + DateTime.Now.ToFileTimeUtc() + ".zip", _directoryDatabaseLocation, false, "database.db");
             */ 
        }
    }
}
